package com.carl.zeus.server.system;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.carl.zeus.common.util.Constant;
import com.carl.zeus.common.util.MapUtils;
import com.carl.zeus.dao.system.SysMenuMapper;
import com.carl.zeus.dao.system.SysUserMapper;
import com.carl.zeus.model.system.SysMenu;
import com.carl.zeus.model.vo.MenuVO;
import com.carl.zeus.model.vo.Tree;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zcm
 * @since 2017-02-10
 */
@Service
public class SysMenuService extends ServiceImpl<SysMenuMapper, SysMenu> {

    @Autowired
    private SysMenuMapper sysMenuMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private SysRoleMenuService sysRoleMenuService;

    public List<SysMenu> queryListParentId(Long parentId, List<Long> menuIdList) {
        List<SysMenu> menuList = queryListParentId(parentId);
        if(menuIdList == null){
            return menuList;
        }

        List<SysMenu> userMenuList = new ArrayList<>();
        for(SysMenu menu : menuList){
            if(menuIdList.contains(menu.getId())){
                userMenuList.add(menu);
            }
        }
        return userMenuList;
    }

    public List<SysMenu> queryListParentId(Long parentId) {
        return sysMenuMapper.queryListParentId(parentId);
    }

    public List<SysMenu> queryNotButtonList() {
        return sysMenuMapper.queryNotButtonList();
    }

    public List<SysMenu> getUserMenuList(Long userId) {
        //系统管理员，拥有最高权限
        if(userId == Constant.SUPER_ADMIN){
            return getAllMenuList(null);
        }

        //用户菜单列表
        List<Long> menuIdList = sysUserMapper.queryAllMenuId(userId);
        return getAllMenuList(menuIdList);
    }

    public List<SysMenu> queryList(Map<String, Object> map) {
        return sysMenuMapper.queryList(map);
    }

    @Transactional
    public void deleteBatch(Long[] menuIds) {
        sysMenuMapper.deleteBatch(menuIds);
    }

    public List<SysMenu> queryUserList(Long userId) {
        return sysMenuMapper.queryUserList(userId);
    }


    /**
     * 获取所有菜单列表
     */
    private List<SysMenu> getAllMenuList(List<Long> menuIdList){
        //查询根菜单列表
        List<SysMenu> menuList = queryListParentId(0L, menuIdList);
        //递归获取子菜单
        getMenuTreeList(menuList, menuIdList);

        return menuList;
    }

    /**
     * 递归
     */
    private List<SysMenu> getMenuTreeList(List<SysMenu> menuList, List<Long> menuIdList){
        List<SysMenu> subMenuList = new ArrayList<>();

        for(SysMenu entity : menuList){
            if(entity.getType() == Constant.MenuType.CATALOG.getValue()){//目录
                entity.setChildren(getMenuTreeList(queryListParentId(entity.getId(), menuIdList), menuIdList));
            }
            subMenuList.add(entity);
        }

        return subMenuList;
    }

    private List<MenuVO> getTreeMenuList(List<SysMenu> menuList) {
        MenuVO menuVO = new MenuVO();
        List<SysMenu> rootMenu = new ArrayList<>();
        for (int i = 0; i < menuList.size(); i++) {
            // 获取根菜单
            SysMenu menu = menuList.get(i);
            if (menu.getParentId() == 0) {
                rootMenu.add(menu);
            }
        }

        for (int j = 0; j < rootMenu.size(); j++) {
        }
        return null;
    }

    public List<SysMenu> listAjax(int page, int limit, String key, String value) {
        List<SysMenu> menuList = sysMenuMapper.selectPage(
                new Page<SysMenu>(page, limit),
                new EntityWrapper<SysMenu>().like(key, value));
        return menuList;
    }

    public Page<SysMenu> selectMenuPage(Page<SysMenu> page, Integer state) {
        page.setRecords(sysMenuMapper.selectMenuList(page, state));
        return page;
    }

    public Page<SysMenu> selectPage(Page<SysMenu> page, String key, String value) {
        page.setRecords(sysMenuMapper.selectPage(page, new EntityWrapper<SysMenu>().like(key, value)));
        return page;
    }

    public Integer countMenuList() {
        return sysUserMapper.selectCount(new EntityWrapper<>());
    }

    /**
     * 新增或者修改资源信息
     * @param menu 资源对象
     * @return
     * @throws Exception
     */
    @Transactional
    public SysMenu saveOrUpdateMenu(SysMenu menu) {
        long start = System.currentTimeMillis();
        try {
            //保存菜单资源信息
            if (null == menu.getId()) {
                menu.setCreateTime(new Date());
                sysMenuMapper.insert(menu);
            } else {
                //更新菜单资源信息
                menu.setUpdateTime(new Date());
                sysMenuMapper.updateById(menu);
            }
        } catch (Exception e) {
            throw e;
        }finally {
        }
        return menu;
    }

    /*删除菜单和关联角色菜单*/
    public void delete(Long id){
        //删除菜单
        this.deleteById(id);
        //删除菜单与角色关联
        sysRoleMenuService.deleteByMap(new MapUtils().put("id", id));
    }

    /**
     * 查询有效的,URL不为空的所有菜单信息
     * @return
     */
    public List<SysMenu> selectMenuUrlAllList() {
        return sysMenuMapper.selectMenuUrlAllList();
    }

    /**
     * 根据用户Id查询用户资源菜单信息
     * @param userId 用户Id
     * @return
     */
    public List<SysMenu> selectMenuListByUserId(Long userId){
        return sysMenuMapper.selectMenuListByUserId(userId);

    }

    /**
     * 查询所有资源信息用以角色赋权限的时候Tree菜单显示
     */
    public List<Tree> selectMenuAllTree() {
        // 菜单资源集合
        List<SysMenu> menuList = sysMenuMapper.selectList(new EntityWrapper<SysMenu>().eq("status", "1").orderBy("sort", true));
        // tree 树形集合
        List<Tree> trees = new ArrayList<>();
        if (null != menuList && !menuList.isEmpty()) {
            for (int i = 0; i < menuList.size(); i++) {
                SysMenu sysMenu = menuList.get(i);
                Tree tree = new Tree();
                tree.setId(sysMenu.getId());
                if (null != sysMenu.getParentId()) {
                    tree.setPid(sysMenu.getParentId());
                }
                if (i == 0){
                    tree.setState("open");
                }
                tree.setText(sysMenu.getName());
                tree.setIconCls(sysMenu.getIcon());
                Map<String, Object> attr = new HashMap<>();
                attr.put("url", sysMenu.getUrl());
                tree.setAttributes(attr);
                trees.add(tree);
            }
        }
        return trees;
    }

    /**
     * 查询所有资源信息用以角色赋权限的时候Tree菜单显示
     */
    public List<MenuVO> selectParentMenuAllTree() {
        // 菜单资源集合
        List<SysMenu> menuList = sysMenuMapper.selectList(new EntityWrapper<SysMenu>().eq("status", "1").in("menu_level", new String[]{"1", "2"}).orderBy("sort", true));
        List<MenuVO> trees = new ArrayList<>();
        if (null != menuList && !menuList.isEmpty()) {
            for (int i = 0; i < menuList.size(); i++) {
                SysMenu menu = menuList.get(i);
                if (menu.getParentId() == 0) {
                    MenuVO item = new MenuVO();
                    item.setId(menu.getId());
                    if (null != menu.getParentId()) {
                        item.setPid(menu.getParentId());
                    }
                    item.setName(menu.getName());
                    item.setIcon(menu.getIcon());
                    if (i == 0){
                        item.setSpread(true);
                    }
                    trees.add(item);
                }
            }

            for (int j = 0; j < trees.size(); j++) {
                List<MenuVO> childrens = new ArrayList<>();
                MenuVO tree = trees.get(j);
                for (int k = 0; k < menuList.size(); k++) {
                    MenuVO children = new MenuVO();
                    children.setId(menuList.get(k).getId());
                    if (null != menuList.get(k).getParentId()) {
                        children.setPid(menuList.get(k).getParentId());
                    }
                    children.setName(menuList.get(k).getName());
                    children.setIcon(menuList.get(k).getIcon());
                    if (menuList.get(k).getParentId().equals(tree.getId())) {
                        childrens.add(children);
                    }
                }
                tree.setChildren(childrens);
            }
        }
        return trees;
    }


}
